home *** CD-ROM | disk | FTP | other *** search
- /* HMDoc.c -- HyperMedia Document base class
- */
-
- /* implements ... */
- #include "HMDoc.h"
-
- /* uses ... */
- #include "HTMLdtd.h"
- #include "SGML.h"
- #include "object.h"
-
- static HMFileWriterProc fileWriter;
- static HMWriterProc writer;
- static HMDeleteProc delete;
- static HMStartTagProc startTag;
- static HMEndTagProc endTag;
- static HMDataProc data;
-
- HMDoc_Class InCore = {fileWriter, writer,
- delete,
- startTag, endTag, data,
- html_entity_text};
-
- typedef struct{
- char* gi;
- int content;
- int nattrs;
- HMBinding* attrs;
- }Tag;
-
- typedef struct _cell{
- struct _cell *first, *rest, *up;
- }Cons;
-
- struct _HMDoc{
- Cons* root;
- Cons* here;
- };
-
-
- /* constructors */
-
- static HMDoc*
- fileWriter(fp)
- FILE* fp;
- {
- return 0; /* this class doesn't write to files */
- }
-
- static HMDoc*
- writer(out, write)
- HMStream out;
- HMWriteProc* write;
- {
- return 0; /* this class doesn't write to streams */
- }
-
- HMDoc*
- InCore_new()
- {
- HMDoc* this = NEW(HMDoc, 1);
- this->root = 0;
- this->here = 0;
- return this;
- }
-
- /* destructors */
-
- static VOID Tag_free PARAMS((Tag* it));
-
- static VOID
- element_free(this)
- Cons* this;
- {
- Cons* c;
-
- if(this->first){
- Cons* next;
- Tag_free((Tag*)this->first);
- for(c = this->rest; c; c = next){
- element_free(c->first);
- next = c->rest;
- FREE(c);
- }
- }else{
- FREE(this->rest); /* data */
- }
- FREE(this);
- }
-
-
- static VOID
- delete(this)
- HMDoc* this;
- {
- if(this->root)
- element_free(this->root);
- }
-
-
-
- /* building routines */
-
- static Tag*
- Tag_new(gi, content, attrs, nattrs)
- CONST char* gi;
- CONST HMBinding attrs[];
- int nattrs;
- {
- Tag* this = NEW(Tag, 1);
- int total = strlen(gi) + 1;
- int i;
- char* p;
-
- for(i = 0; i<nattrs; i++)
- total += strlen(attrs[i].name) + 1
- + strlen(attrs[i].value) + 1;
-
- this->gi = NEW(char, total);
- this->content = content;
- this->attrs = NEW(HMBinding, nattrs);
- this->nattrs = nattrs;
-
- strcpy(this->gi, gi);
- p = this->gi;
- while(*p++);
-
- for(i=0; i<nattrs; i++){
- strcpy(this->attrs[i].name = p, attrs[i].name);
- while(*p++);
- strcpy(this->attrs[i].value = p, attrs[i].value);
- while(*p++);
- }
- return this;
- }
-
- static VOID
- Tag_free(this)
- Tag* this;
- {
- FREE(this->gi);
- FREE(this->attrs);
- }
-
-
- static Cons*
- cons(car, cdr, parent)
- VOIDPTR car;
- VOIDPTR cdr;
- Cons* parent;
- {
- Cons* this = NEW(Cons, 1);
- this->first = (Cons*)car;
- this->rest = (Cons*)cdr;
- this->up = parent;
- return this;
- }
-
-
- static VOID
- attach(this, element, data)
- HMDoc* this;
- Tag* element;
- CONST char* data;
- {
- Cons* it = cons(element, data);
-
- if(this->here){
- Cons* cell = cons(it, 0, this->here->up);
- this->here->rest = cell;
- this->here = cell;
- }else{
- this->root = this->here = it;
- }
- }
-
-
- static int
- startTag(this, gi, attributes, nattrs)
- HMDoc* this;
- CONST char* gi;
- CONST HMBinding attributes[];
- int nattrs;
- {
- int c = HTML_content(gi);
- Tag* nt = Tag_new(gi, c, attributes, nattrs); /* content? @@*/
-
- attach(this, nt, 0);
-
- return c;
- }
-
-
- static VOID
- endTag(this, gi)
- HMDoc* this;
- CONST char* gi;
- {
- if(this->here && this->here->up)
- this->here = this->here->up;
- }
-
-
- static VOID
- data(this, data, qty)
- HMDoc* this;
- CONST char* data;
- int qty;
- {
- if(this->here){
- char* nd = NEW(char, qty+sizeof(int));
- *((int*)nd) = qty;
- memcpy(nd + sizeof(int), data, qty);
- attach(this, 0, nd);
- }
- }
-
-
- /* traverse the document */
-
- static VOID
- element_traverse(this, dest, docclass)
- Cons* this;
- HMDoc* dest;
- HMDoc_Class* docclass;
- {
- Cons* c;
-
- if(this->first){
- Tag* t = (Tag*)(this->first);
- (docclass->startTag)(dest, t->gi, t->attrs, t->nattrs);
- if(t->content != SGML_EMPTY){
- for(c = this->rest; c; c = c->rest)
- element_traverse(c->first, dest, docclass);
- (docclass->endTag)(dest, t->gi);
- }
- }else{
- int q = *((int*)(this->rest));
- char* d = ((char*)(this->rest)) + sizeof(int);
- (docclass->data)(dest, d, q);
- }
- }
-
- VOID
- InCore_traverse(this, that, c)
- HMDoc* this;
- HMDoc* that;
- HMDoc_Class* c;
- {
- element_traverse(this->root, that, c);
- }
-